package com.dogsong.liteflow.editor.service.impl;

import com.dogsong.liteflow.editor.bean.*;
import com.dogsong.liteflow.editor.parser.generator.ExpressGenerator;
import com.dogsong.liteflow.editor.service.BizService;
import com.google.common.collect.Lists;
import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.flow.element.Chain;
import com.yomahub.liteflow.flow.element.Node;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * BizServiceImpl
 *
 * @author <a href="mailto:dogsong99@163.com">dosong</a>
 * @since 2024/6/12
 */
@Slf4j
public class BizServiceImpl implements BizService {

    @Autowired
    private ExpressGenerator expressGenerator;

    @Override
    public List<CmpInfoVO> getCmpList() {
        Map<String, Node> nodeMap = FlowBus.getNodeMap();
        if (nodeMap.isEmpty()) {
            return Collections.emptyList();
        }
        List<CmpInfoVO> cmpList = Lists.newArrayListWithExpectedSize(nodeMap.size());

        FlowBus.getNodeMap().keySet().forEach(nodeId ->
                cmpList.add(
                        CmpInfoVO.builder()
                                .cmpId(FlowBus.getNode(nodeId).getId())
                                .cmpName(FlowBus.getNode(nodeId).getName())
                                .build()
                )
        );

        return cmpList;
    }

    @Override
    public List<ChainInfoVO> getChainList() {
        Map<String, Chain> chainMap = FlowBus.getChainMap();
        if (chainMap.isEmpty()) {
            return Collections.emptyList();
        }

        List<ChainInfoVO> chainList = Lists.newArrayListWithExpectedSize(chainMap.size());
        FlowBus.getChainMap().values().forEach(chain ->
                chainList.add(
                        ChainInfoVO.builder()
                                .chainId(chain.getId())
                                .chainName("中文别名-".concat(chain.getId()))
                                .build()
                )
        );

        return chainList;
    }

    @Override
    public VerificationResult verifyELExpression(CmpProperty jsonEl) {
        boolean verified = expressGenerator.verifyELExpression(jsonEl);
        if (!verified) {
            return VerificationResult.builder().code("E").message("校验失败").build();
        }
        return VerificationResult.builder().code("S").message("校验通过").build();
    }

    @Override
    public CommonResult createChain(CreateChainVO createChainVO) {
        if (null == createChainVO.getChainId()) {
            return CommonResult.builder().code("E").message("构建失败,ChainId为空").build();
        }
        if (FlowBus.getChainMap().containsKey(createChainVO.getChainId())) {
            return CommonResult.builder().code("E").message("构建失败,ChainId已存在").build();
        }

        try {
            ELInfo generateEL = expressGenerator.generateEL(createChainVO.getElJson());
            String elStr = generateEL.getElStr();
            LiteFlowChainELBuilder.createChain()
                    .setChainId(createChainVO.getChainId())
                    .setEL(elStr).build();
        } catch (Exception ex) {
            return CommonResult.builder().code("E").message("构建失败,".concat(ex.getMessage())).build();
        }
        return CommonResult.builder().code("S").message("构建成功").build();
    }

    @Override
    public CommonResult deleteChain(DeleteChainVO deleteChainVO) {
        if (!FlowBus.getChainMap().containsKey(deleteChainVO.getChainId())) {
            return CommonResult.builder().code("E").message("销毁失败,ChainId不存在").build();
        }
        try {
            FlowBus.removeChain(deleteChainVO.getChainId());
        } catch (Exception ex) {
            return CommonResult.builder().code("E").message("销毁失败,".concat(ex.getMessage())).build();
        }
        return CommonResult.builder().code("S").message("销毁成功").build();
    }

    @Override
    public CommonResult updateChain(UpdateChainVO updateChainVO) {
        if (null == updateChainVO.getChainId()) {
            return CommonResult.builder().code("E").message("更新失败,ChainId为空").build();
        }
        if (!FlowBus.getChainMap().containsKey(updateChainVO.getChainId())) {
            return CommonResult.builder().code("E").message("更新失败,ChainId不存在").build();
        }
        try {
            ELInfo generateEL = expressGenerator.generateEL(updateChainVO.getElJson());
            String updateELStr = generateEL.getElStr();
            LiteFlowChainELBuilder.createChain()
                    .setChainId(updateChainVO.getChainId())
                    .setEL(updateELStr).build();
        } catch (Exception ex) {
            return CommonResult.builder().code("E").message("更新失败,".concat(ex.getMessage())).build();
        }
        return CommonResult.builder().code("S").message("构建成功").build();
    }

    @Override
    public ChainInfo getChainById(String chainId) {
        String elStr = StringUtils.trim(FlowBus.getChain(chainId).getEl());
        log.info("ChainId:[{}] 对应的 el表达式:[{}].", chainId, elStr);

        ELInfo elInfo = new ELInfo();
        elInfo.setChainId(chainId);
        elInfo.setElStr(elStr);

        // json构建
        CmpProperty cmpProperty = expressGenerator.generateJsonEL(elInfo);

        return ChainInfo.builder()
                .elInfo(elInfo)
                .elJson(cmpProperty)
                .build();
    }

}
